﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharp.Libs.Koc;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using CSharp.Libs.Koc.ItemClasses;
using System.Collections;
using CSharp.Libs.Koc.KernelModels;

namespace CSharp.Libs.WPF.UserControls
{
    public class KocCitySelectorViewModel : ViewModelBase
    {
        #region declarations
        private Dispatcher _DISP = null;
        private Kernel _KRNL = null;

        private ObservableCollection<CityItem> _ocCityList = new ObservableCollection<CityItem>();

        private CityItem _selectedCity = null;

        private CityItem _ciNoServerUser = null;    //shows up in Citybox when no User or Server is selected in KernelControl
        private CityItem _ciNoSeed = null;          //shows up in Citybox when the selected User - Server combo didn't receive a seed yet

        private int _intServerNr = 0;
        private string _strUserFbUid = "";

        private const string NO_SERVER_USER = "<No server/user selected>";
        private const string NO_SEED = "<No seed yet>";

        #region events
        public delegate void CitySelectedEventHandler(object sender, SelectedCityEventArgs scea);
        public event CitySelectedEventHandler CitySelected;
        private void ThrowCitySelectedEvent(
            SelectedCityEventArgs scea)
        {
            if (CitySelected != null)
            {
                CitySelected(this, scea);
            }
        }
        #endregion
        #endregion



        #region constructor / finalizer
        public KocCitySelectorViewModel(
            Dispatcher DISP,
            Kernel KRNL)
        {
            _DISP = DISP;
            _KRNL = KRNL;

            _KRNL.SC.SeedReceived += new SeedCollector.SeedReceivedEventHandler(SC_SeedReceived);

            _initTempCities();
        }
        #endregion



        #region event handling
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="srea"></param>
        /// <history>created  26.06.2012</history>
        void SC_SeedReceived(object sender, SeedReceivedEventArgs srea)
        {
            //build city list
            _createCityList();//HIER doch nicht... tztz // KLAR hier. Wenn User und Server schon ausgewählt sind und der nur noch auf den Seed wartet???? Mann mann....
        }
        #endregion



        #region private functions
        /// <summary>
        /// 
        /// </summary>
        /// <history>created  28.06.2012</history>
        private void _initTempCities()
        {
            _ciNoServerUser = new CityItem();
            _ciNoServerUser.CityName = NO_SERVER_USER;

            _ciNoSeed = new CityItem();
            _ciNoSeed.CityName = NO_SEED;

            _AddCity(_ciNoServerUser);
            SelectedCity = _ciNoServerUser;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  27.06.2012</history>
        private void _createCityList()
        {
            //clear citylist
            _clearCities();

            //switch to select first city
            bool fFirstCity = true;

            //check if user and server are selected
            if (UserFbUid != "" &&
               ServerNr > 0)
            {
                //check if seed was received
                string strKey = _KRNL.SC.GetKey(UserFbUid, ServerNr.ToString());
                if (_KRNL.SC.Seeds.ContainsKey(strKey))
                {
                    //build city list
                    SeedHolder SH = new SeedHolder(_KRNL, _KRNL.SC.Seeds[strKey] as Hashtable);

                    foreach (KeyValuePair<string, CityItem> KVP in SH.Cities)
                    {
                        CityItem ciCurrent = KVP.Value;

                        _AddCity(ciCurrent);

                        //select first city automatically
                        if (fFirstCity)
                        {
                            setSelectedCity(ciCurrent);
                            fFirstCity = false;
                        }
                    }
                }
                else
                {
                    _AddCity(_ciNoSeed);
                    SelectedCity = _ciNoSeed;
                }
            }
            else
            {
                _AddCity(_ciNoServerUser);
                SelectedCity = _ciNoServerUser;
            }
        }

        #region UI-invokes
        /// <summary></summary>
        /// <history>created  27.06.2012</history>
        private void _clearCities()
        {
            _DISP.Invoke((Action)delegate
            {
                _ocCityList.Clear();
                SelectedCity = null;
                OnPropertyChanged("Cities");
                OnPropertyChanged("SelectedCity");
            });
        }

        /// <summary></summary>
        /// <param name="CI"></param>
        /// <history>created  27.06.2012</history>
        private void _AddCity(
            CityItem CI)
        {
            _DISP.Invoke((Action)delegate
            {
                _ocCityList.Add(CI);
                OnPropertyChanged("Cities");
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ciSelect"></param>
        /// <history>created  28.06.2012</history>
        private void setSelectedCity(
            CityItem ciSelect)
        {
            _DISP.Invoke((Action)delegate
            {
                SelectedCity = ciSelect;
                OnPropertyChanged("SelectedCity");
            });
        }
        #endregion
        #endregion



        #region interface
        #region properties
        /// <summary>
        /// 
        /// </summary>
        /// <history>created  26.06.2012</history>
        public ObservableCollection<CityItem> Cities { get { return _ocCityList; } }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  26.06.2012</history>
        public CityItem SelectedCity
        {
            get { return _selectedCity; }
            set
            {
                _selectedCity = value;
                if (_selectedCity != null)
                {
                    OnPropertyChanged("SelectedCity");

                    if (_selectedCity != _ciNoServerUser && 
                        _selectedCity != _ciNoSeed)
                    {
                        ThrowCitySelectedEvent(new SelectedCityEventArgs(_selectedCity));
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  09.07.2012</history>
        public int ServerNr { get { return _intServerNr; } set { _intServerNr = value; _createCityList(); } }

        /// <summary>
        /// 
        /// </summary>
        /// <history>created  09.07.2012</history>
        public string UserFbUid { get { return _strUserFbUid; } set { _strUserFbUid = value; _createCityList(); } }
        #endregion

        #region methods
        #endregion
        #endregion
    }
}
